/*
 * ServerSideHandler.java
 *
 * Created on July 24, 2007, 4:51 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.mar.bt.rd.server;

import java.awt.AWTException;
import java.awt.Robot;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;

import com.mar.bt.server.IBluetoothIOHandler;

/**
 *
 * @author helio
 */
public class ServerSideHandler {
 
	private InputStream inputStream;
    private OutputStream outputStream;
    
    private Thread inputStreamListenerThread;
    private Thread screenshotCreatorThread;
    
    private Robot robot;
    
    private KeyboardHandler keyboardHandler;
    private MouseHandler mouseHandler;
    private ScreenHandler screenHandler;
    
    /**
     * Creates a new instance of ServerSideHandler
     *
     * @param server
     * @param email
     * @param password
     * @param socket
     * @throws java.io.IOException
     * @throws java.awt.AWTException
     */
    public ServerSideHandler(IBluetoothIOHandler btHandler) throws IOException, AWTException {
    	inputStream = btHandler.getInputStream();
    	outputStream = btHandler.getOutputStream();
        
        /* creates the input stream listener */
        inputStreamListenerThread = new Thread(new Runnable() {
            public void run() {
                try {
//                    byte[] cool_message = IDesktopProtocol.createMessage(IDesktopProtocol.AUTHENTICATION_SUCCESSFUL_MESSAGE, "Authentication successful!");
//                    Thread.sleep(1000);
//                    outputStream.write("left".getBytes());	
//                	outputStream.flush();
                    while (true) {
                        byte[] message = IDesktopProtocol.readMessage(inputStream);
                        String operation = IDesktopProtocol.getOperation(message);
                        byte[] params = IDesktopProtocol.getParameters(message);
                        processMessage(operation, params);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        
        /* initialize handlers */
        robot = new Robot();
        keyboardHandler = new KeyboardHandler(robot);
        mouseHandler = new MouseHandler(robot);
        screenHandler = new ScreenHandler(robot);
        
        /* start comunicating */
        inputStreamListenerThread.start();
    }
    
    /**
     *
     * @throws java.io.IOException
     */
    public void sendAuthenticationMessage() throws IOException {
        Vector<String> params = new Vector<String>();
        byte[] message = IDesktopProtocol.createMessage(IDesktopProtocol.AUTHENTICATION_MESSAGE, params);
        sendMessage(message);
    }
    
    /**
     *
     * @param bytes
     * @throws java.io.IOException
     */
    public void sendScreenshotMessage(byte[] bytes) throws IOException {
        final Vector<String> params = IDesktopProtocol.parseParameters(bytes);
        
        screenshotCreatorThread = new Thread(new Runnable() {
            public void run() {
                try {
                    int x = Integer.parseInt((String) params.elementAt(0));
                    int y = Integer.parseInt((String) params.elementAt(1));
                    int width = Integer.parseInt((String) params.elementAt(2));
                    int height = Integer.parseInt((String) params.elementAt(3));
                    
                    byte[] imageBytes = screenHandler.createScreenCapture(x, y, width, height);
                    byte[] message = IDesktopProtocol.createMessage(IDesktopProtocol.SCREENSHOT_MESSAGE, imageBytes);
                    System.out.println("Gonna send an array "+message.length);
                    sendMessage(message);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        
        screenshotCreatorThread.start();
    }
    
    /**
     *
     * @param bytes
     */
    public void receiveDeviceConfigurationMessage(byte[] bytes) {
        Vector<String> params = IDesktopProtocol.parseParameters(bytes);
        int deviceWidth = Integer.parseInt((String) params.elementAt(0));
        int deviceHeight = Integer.parseInt((String) params.elementAt(1));
        
        mouseHandler.setDeviceWidth(deviceWidth);
        mouseHandler.setDeviceHeight(deviceHeight);
        screenHandler.setDeviceWidth(deviceWidth);
        screenHandler.setDeviceHeight(deviceHeight);
    }
    
    /**
     *
     * @param params
     */
    private void performClientAuthentication(byte[] bytes) throws IOException {
            byte[] message = IDesktopProtocol.createMessage(IDesktopProtocol.AUTHENTICATION_SUCCESSFUL_MESSAGE, "Authentication successful!");
            sendMessage(message);
    }
    
    /**
     *
     * @param operation
     * @param params
     */
    public void processMessage(String operation, byte[] params) throws IOException {
        if (operation.equals(IDesktopProtocol.AUTHENTICATION_MESSAGE)) {
            performClientAuthentication(params);
        } else if (operation.equals(IDesktopProtocol.REQUEST_SCREENSHOT_MESSAGE)) {
            sendScreenshotMessage(params);
        } else if (operation.equals(IDesktopProtocol.DEVICE_CONFIGURATION_MESSAGE)) {
            receiveDeviceConfigurationMessage(params);
        } else if (operation.equals(IDesktopProtocol.MOUSE_LEFT_CLICK_MESSAGE)) {
            mouseHandler.clickLeftButton(params);
        } else if (operation.equals(IDesktopProtocol.MOUSE_RIGHT_CLICK_MESSAGE)) {
            mouseHandler.clickRightButton(params);
        } else if (operation.equals(IDesktopProtocol.MOUSE_LEFT_PRESS_MESSAGE)) {
            mouseHandler.pressLeftButton(params);
        } else if (operation.equals(IDesktopProtocol.MOUSE_LEFT_RELEASE_MESSAGE)) {
            mouseHandler.releaseLeftButton(params);
        } else if (operation.equals(IDesktopProtocol.MOUSE_RIGHT_PRESS_MESSAGE)) {
            mouseHandler.pressRightButton(params);
        } else if (operation.equals(IDesktopProtocol.MOUSE_RIGHT_RELEASE_MESSAGE)) {
            mouseHandler.releaseRightButton(params);
        } else if (operation.equals(IDesktopProtocol.MOUSE_MOVE_MESSAGE)) {
            mouseHandler.moveMouse(params);
        } else if (operation.equals(IDesktopProtocol.KEYBOARD_INPUT_MESSAGE)) {
            keyboardHandler.typeKeys(params);
        }
    }
    
    /**
     *
     * @param message
     * @throws java.io.IOException
     */
    public void sendMessage(byte[] message) throws IOException {
        outputStream.write(message);
        outputStream.flush();
    }
    
    /**
     *
     * @throws java.io.IOException
     */
    public void close() throws IOException {
        inputStream.close();
        outputStream.flush();
        outputStream.close();
    }
    
    /**
     *
     * @return
     */
    
    /**
     *
     * @return
     */
    public InputStream getInputStream() {
        return inputStream;
    }
    
    /**
     *
     * @return
     */
    public OutputStream getOutputStream() {
        return outputStream;
    }
    
}
